package
{
	import core.battle.RockObject;
	import core.battle.SpaceShipObject;
	import core.battle.TailObject;
	
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.utils.getTimer;
	
	public class Game extends Sprite
	{
		private static var _instance : Game;
		
		public static const WIDTH: Number = 600;
		public static const HEIGHT : Number = 300;
		
		private var _forwardSpeed : Number = 5e-2;
		
		public function get spaceShip():SpaceShipObject
		{
			return _spaceShip;
		}

		public function get forwardSpeed():Number
		{
			return _forwardSpeed;
		}

		public function get mousePressed():Boolean
		{
			return _mousePressed;
		}
		
		public static function getInstance() : Game {
			if( !_instance ) {
				_instance = new Game( );
			}
			return _instance;
		}
		
		private var _lastTime :Number = getTimer();
		
		public function Game( ) {
			super();
			var backGround : Shape = new Shape();
			backGround.graphics.beginFill( 0x000000);
			backGround.graphics.drawRect( 0 , 0 , WIDTH ,  HEIGHT);
			backGround.graphics.endFill();
			backGround.x = 0;
			backGround.y = 0;
			this.addChild( backGround );
			addEventListener(Event.ENTER_FRAME , onEnterFrame );
			addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown );
			addEventListener(MouseEvent.MOUSE_UP, onMouseUp );
			gameInit();
		}
		
		
		private var _mousePressed : Boolean = false;
		
		private function onMouseDown( evt : MouseEvent) : void {
			if( !_mousePressed ) {
				_mousePressed = true;
			}
		}
		
		private function onMouseUp(evt : MouseEvent) : void {
			if( _mousePressed ) {
				_mousePressed = false;
			}
		}
		
		private const FRAME_RATE :Number = 50;
		
		private function onEnterFrame( evt : Event ) : void {
			var deltaTime : Number = getTimer() - _lastTime;
			if( deltaTime * FRAME_RATE > 1000 ) {
				gameLoop( deltaTime );
				_lastTime = getTimer();
			}
		}
		
		private var _spaceShip : SpaceShipObject;	
		private var _tails : Array;
		private var _tailsNum : int;
		private const _maxTailsNum : int = 100;
		
		private var _rocks : Array;
		private var _rocksNum : int;
		private var _maxRoacksNum : int = 10;
		
		public function gameInit() : void {
			_spaceShip = new SpaceShipObject();
			_spaceShip.init();
			addChild(_spaceShip );
			
			_tails = new Array();
			for( var i : int = 0 ; i < _maxTailsNum ; ++i ) {
				_tails[ i ] = new TailObject();
				( _tails[ i ] as TailObject ).init();
				( _tails[ i ] as TailObject ).visible = false;
			}
			_tailsNum = 0;
			
			_rocks = new Array();
			for( var ri : int = 0 ; ri < _maxRoacksNum ; ++ri ) {
				_rocks[ ri ]= new RockObject();
				( _rocks[ri] as RockObject ).init();
				( _rocks[ri] as RockObject ).visible = false;
			}
			_rocksNum = 0;
		}
		
		private const _powerPeriod : int = 100;
		private var _powerPeriodCount : int = 0;
		
		private const _rocksPeriod : int = 1000;
		private var _rocksPeriodCount :int = 0;
		
		public function gameLoop( deltaTime : Number ) : void {
			if( _spaceShip ) {
				_spaceShip.update(deltaTime);
			}
			
			for each( var tail : TailObject in _tails ) {
				tail.update( deltaTime );
				if( !tail.isIn() ) {
					if( contains( tail ) ) {
						removeChild( tail );
					}
				}
			}
			
			for each( var rock:RockObject in _rocks ) {
				rock.update(deltaTime);
				if( !rock.isIn() ) {
					if (contains(rock)) {
						removeChild( rock );
						--_rocksNum;
					}
				}
				
				if( rock.isHit( _spaceShip ) ){
					_spaceShip.setDefault();
				}
			}
			
			if( _powerPeriodCount <= _powerPeriod ) {
				_powerPeriodCount += deltaTime;
			} else {
				if( _mousePressed ) {
					var tailToAdd : TailObject = _tails[ _tailsNum % _maxTailsNum ];
					_tailsNum ++;
					tailToAdd.x = _spaceShip.x;
					tailToAdd.y = _spaceShip.y;
					if( !contains( tailToAdd ) ) {
						addChild( tailToAdd );
					}
					tailToAdd.visible = true;
				}
				_powerPeriodCount = 0;
			}
			
			if( _rocksPeriodCount <= _rocksPeriod ) {
				_rocksPeriodCount += deltaTime;
			} else {
				if( _rocksNum < _maxRoacksNum ) {
					for each( var rockToFind : RockObject in _rocks ) {
						if( !contains(rockToFind ) ) {
							addChild ( rockToFind );
							rockToFind.x = Game.WIDTH;
							rockToFind.y = Game.HEIGHT * Math.random();
							rockToFind.visible = true;
							rockToFind.resetSpeed();
							_rocksNum++;
							break;
						}
					}
				}
				_rocksPeriodCount = 0;
			}
		}
	}
}